<template>
  <el-dialog v-model="visible" :title="dialogTitle" :width="dialogWidth" :append-to-body="true">
    <vxe-table ref="tableRef" :data="paginationRes.data" :height="dialogHeight">
      <vxe-column type="seq" title="序号" width="50"></vxe-column>
      <vxe-column
        v-for="item in dictConfig?.items || []"
        v-show="item.easySearcher"
        :key="item.columnName"
        :field="item.columnName"
        :title="item.displayName"
        :width="item.displayWidth"
      />
      <vxe-column title="操作" width="100" fixed="right">
        <template #default="{ row }">
          <el-button type="primary" size="small" @click="onSelectItem(row)">选择</el-button>
        </template>
      </vxe-column>
    </vxe-table>

    <el-pagination
      background
      layout="total, sizes, prev, pager, next, jumper"
      :total="paginationRes?.total"
      :page-size="pageSize"
      :page-sizes="[10, 20, 30, 40]"
      :current-page="currentPage"
      style="margin-top: 10px"
      size="small"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />

    <template #footer>
      <div style="display: flex; flex-direction: row; gap: 10px; align-items: center; margin: 10px">
        <el-icon size="small">
          <el-tooltip effect="dark" :content="tooltipContent" placement="top">
            <QuestionFilled />
          </el-tooltip>
        </el-icon>
        <el-input
          ref="inputRef"
          v-model="queryText"
          placeholder="请输入查询内容"
          clearable
          style="width: 200px"
          @keyup.enter="keyUpOperate('enter')"
          @keyup.up="keyUpOperate('up')"
          @keyup.down="keyUpOperate('down')"
        ></el-input>
        <el-button type="primary" @click="refresh">刷新</el-button>
        <el-button type="danger" @click="visible = false">关闭</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { computed, nextTick, onMounted, ref, watch } from 'vue'
import type { VxeTableInstance } from 'vxe-pc-ui/types/components/table'
import type VxeTable from 'vxe-pc-ui/types/components/table'
import type { PaginationRes } from '@/api/common'
import { DictAPIs, EnumDictName, EnumDictType, type DictConfig } from '@/api/system/dict'
import type { ElInput } from 'element-plus'
import { ElMessage } from 'element-plus'
import { List } from 'linqts'

const props = defineProps({
  dictName: {
    type: Object as () => EnumDictName,
    required: true,
  },
  dialogHeight: {
    type: Number,
    default: 400,
  },
  dialogWidth: {
    type: Number,
    default: 800,
  },
})

const emit = defineEmits(['getResult'])

const visible = ref(false)
const inputRef = ref<InstanceType<typeof ElInput>>()
const currentPage = ref(1)
const pageSize = ref(10)
const queryText = ref('')

const tableRef = ref<VxeTableInstance<any>>()
const dictConfig = ref<DictConfig | undefined>(undefined)
const paginationRes = ref<PaginationRes<any>>({
  total: 0,
  data: [],
})

// 初始化
onMounted(async () => {
  dictConfig.value = await DictAPIs.getDictConfig(props.dictName)
  dictConfig.value.items = new List(dictConfig.value.items).OrderBy(x => x.displaySort).ToArray()
})

// 监听查询条件
watch(
  () => [queryText.value, currentPage.value, pageSize.value],
  async () => {
    await getData()
  }
)

// 窗口显示
watch(
  () => visible.value,
  async newVal => {
    if (newVal) {
      if ((dictConfig?.value?.items ?? []).length <= 0) {
        ElMessage.warning(`字典还未配置，请先配置后再试,字典名称 [${EnumDictName[props.dictName]}] `)
        visible.value = false
        return
      }
      await getData()
    }
  }
)

// 提示内容
const tooltipContent = computed(() => {
  return `${dictConfig?.value?.dictName || ''},${dictConfig?.value?.tableName || ''}`
})

// 对话框标题
const dialogTitle = computed(() => {
  return `${dictConfig?.value?.dictName || ''}`
})

//#region 数据操作
// 选择行
const onSelectItem = (row: any) => {
  emit('getResult', row)
  visible.value = false
}

// 刷新
const refresh = async () => {
  currentPage.value = 1
  pageSize.value = 10

  await getData()
}

// 获取数据
const getData = async () => {
  paginationRes.value = await DictAPIs.getDataByPagination({
    dictName: props.dictName,
    queryText: '',
    isPagination: false,
    currentPage: 0,
    pageSize: 0,
  })

  // 设置输入框焦点
  nextTick(() => {
    inputRef.value?.focus()

    const $table = tableRef.value
    if ($table) {
      $table.setCurrentRow($table?.getFullData()[0])
    }
  })
}

// 键盘事件
const keyUpOperate = (type: string) => {
  const $table = tableRef.value
  if (!$table) {
    return
  }
  const rowIndex = $table.getRowIndex($table.getCurrentRecord())
  // 确定
  if (type === 'enter') {
    onSelectItem($table.getCurrentRecord())
  }

  // 上一行
  if (type === 'up') {
    if (rowIndex > 0) {
      $table.setCurrentRow($table.getFullData()[rowIndex - 1])
    } else {
      if (currentPage.value > 1) {
        currentPage.value--
      } else {
        currentPage.value = totalPages.value
      }

      getData()
    }
  }

  // 下一行
  if (type === 'down') {
    if (rowIndex < $table.getFullData().length - 1) {
      $table.setCurrentRow($table.getFullData()[rowIndex + 1])
    } else {
      if (currentPage.value < totalPages.value) {
        currentPage.value++
        getData()
      }
    }
  }
}
//#endregion

//#region 分页数据

// 总页数
const totalPages = computed(() => {
  if (paginationRes.value?.total === 0) {
    return 0
  } // 总条数为0时，总页数为0
  return Math.ceil(paginationRes.value?.total / pageSize.value)
})

// 分页大小改变
const handleSizeChange = (val: number) => {
  pageSize.value = val
}

// 分页当前页改变
const handleCurrentChange = (val: number) => {
  currentPage.value = val
}
//#endregion
defineExpose({ visible })
</script>

<style lang="scss" scoped></style>
